1. Proyecto 1.2. Entrega 2 - Exploración y Análisis de Datos (EDA) Objetivo: Realizar una exploración y análisis exhaustivo del conjunto de datos proporcionado, utilizando técnicas de EDA para comprender la estructura de los datos, identificar patrones y preparar los datos para el modelado. Descripción de la segunda actividad:
  2. Exploración Inicial de Datos: Carga del Dataset: Cargar el conjunto de datos en el entorno de trabajo. Asegurarse de que los datos se hayan cargado correctamente y se encuentren en el formato adecuado. Revisión General: Realizar una revisión general del conjunto de datos para obtener una visión inicial de su estructura. Incluyan el número de filas y columnas, nombres de columnas, y tipos de datos de cada columna.
  3. Análisis Univariado: Distribución de Variables: Realizar un análisis de las variables individuales para entender su distribución. Utilizar histogramas, boxplots y estadísticas descriptivas (media, mediana, desviación estándar, etc.) para las variables numéricas. Para las variables categóricas, calcular frecuencias y proporciones. Identificación de Outliers: Detectar posibles outliers en las variables numéricas utilizando técnicas como el análisis de boxplots o el cálculo del z-score.
  4. Análisis Bivariado: Relaciones entre Variables: Analizar la relación entre pares de variables para identificar patrones o correlaciones. Utilizar gráficos de dispersión (scatter plots) y mapas de calor de correlación (heatmaps) para evaluar la relación entre variables numéricas. Comparaciones Categóricas: Explorar cómo las variables categóricas afectan a las variables numéricas, utilizando gráficos de barras y boxplots.
  5. Limpieza de Datos: Tratamiento de Valores Faltantes: Identificar valores faltantes en el conjunto de datos. Aplicar métodos adecuados para el tratamiento de estos valores, ya sea mediante imputación, eliminación de filas/columnas o sustitución con valores medianos/modales. Normalización y Transformación: Realizar transformaciones necesarias para preparar los datos para el análisis posterior. Esto puede incluir normalización y estandarización
In [1]:
import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import seaborn as sns; sns.set(style="ticks", color_codes=True)
import matplotlib.pyplot as plt
import plotly.graph_objs as go
from plotly.subplots import make_subplots
import seaborn as sns
import plotly.express as px
%matplotlib inline

from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected = False)
C:\Users\Usuario\anaconda3\lib\site-packages\pandas\core\arrays\masked.py:60: UserWarning: Pandas requires version '1.3.6' or newer of 'bottleneck' (version '1.3.5' currently installed).
  from pandas.core import (

Exploración Inicial de Datos:
Carga del Dataset:
Cargar el conjunto de datos en el entorno de trabajo.
Asegurarse de que los datos se hayan cargado correctamente y se encuentren en el formato adecuado.
Revisión General:
Realizar una revisión general del conjunto de datos para obtener una visión inicial de su estructura. Incluyan el número de filas y columnas, nombres de columnas, y tipos de datos de cada columna.

Cargar el conjunto de datos en el entorno de trabajo

Realizar una revisión general

In [2]:
# dataset original
df_1=pd.read_csv('C:\\Users\\Usuario\\Desktop\\2024\\materias\\CDIA\\2semestre\\pp1-cdia23\\ejemplo suply chain\\DataCoSupplyChainDataset.csv\\para jupyter\\SinAcento.csv', encoding='latin1', sep=';',  low_memory=False)
pd.set_option('display.max_rows', 60)    #muestra 60 columnas
pd.set_option('display.max_columns', 100)  # 100 filas
pd.set_option('display.width', 1000)
# detalle
df_1.head()
Out[2]:
Type Days for shipping (real) Days for shipment (scheduled) Benefit per order Sales per customer Delivery Status Late_delivery_risk Category Id Category Name Customer City Customer Country Customer Email Customer Fname Customer Id Customer Lname Customer Password Customer Segment Customer State Customer Street Customer Zipcode Department Id Department Name Latitude Longitude Market Order City Order Country Order Customer Id order date (DateOrders) Order Id Order Item Cardprod Id Order Item Discount Order Item Discount Rate Order Item Id Order Item Product Price Order Item Profit Ratio Order Item Quantity Sales Order Item Total Order Profit Per Order Order Region Order State Order Status Order Zipcode Product Card Id Product Category Id Product Description Product Image Product Name Product Price Product Status shipping date (DateOrders) Shipping Mode
0 DEBIT 3 4 9.125000e+01 3.146400e+09 Advance shipping 0 73 Sporting Goods Caguas Puerto Rico XXXXXXXXX Cally 20755 Holloway XXXXXXXXX Consumer PR 5365 Noble Nectar Island 725.0 2 Fitness 182.514.534 -6.603.705.597 Pacific Asia Bekasi Indonesia 20755 1/31/2018 22:56 77202 1360 1.310.999.966 0.04 180517 327.75 0.289999992 1 327.75 3.146.400.146 91.25 Southeast Asia Java Occidental COMPLETE NaN 1360 73 NaN http://images.acmesports.sports/Smart+watch Smart watch 327.75 0 2/3/2018 22:56 Standard Class
1 TRANSFER 5 4 -2.490900e+09 3.113600e+09 Late delivery 1 73 Sporting Goods Caguas Puerto Rico XXXXXXXXX Irene 19492 Luna XXXXXXXXX Consumer PR 2679 Rustic Loop 725.0 2 Fitness 1.827.945.137 -660.370.636 Pacific Asia Bikaner India 19492 1/13/2018 12:27 75939 1360 1.638.999.939 0.05 179254 327.75 -0.800000012 1 327.75 3.113.599.854 -2.490.899.963 South Asia Rajastán PENDING NaN 1360 73 NaN http://images.acmesports.sports/Smart+watch Smart watch 327.75 0 1/18/2018 12:27 Standard Class
2 CASH 4 4 -2.477800e+09 3.097200e+09 Shipping on time 0 73 Sporting Goods San Jose EE. UU. XXXXXXXXX Gillian 19491 Maldonado XXXXXXXXX Consumer CA 8510 Round Bear Gate 95125.0 2 Fitness 3.729.223.251 -121.881.279 Pacific Asia Bikaner India 19491 1/13/2018 12:06 75938 1360 1.803.000.069 0.06 179253 327.75 -0.800000012 1 327.75 3.097.200.012 -2.477.799.988 South Asia Rajastán CLOSED NaN 1360 73 NaN http://images.acmesports.sports/Smart+watch Smart watch 327.75 0 1/17/2018 12:06 Standard Class
3 DEBIT 3 4 2.286000e+09 3.048100e+09 Advance shipping 0 73 Sporting Goods Los Angeles EE. UU. XXXXXXXXX Tana 19490 Tate XXXXXXXXX Home Office CA 3200 Amber Bend 90027.0 2 Fitness 3.412.594.605 -1.182.910.156 Pacific Asia Townsville Australia 19490 1/13/2018 11:45 75937 1360 2.294.000.053 0.07 179252 327.75 0.079999998 1 327.75 3.048.099.976 2.286.000.061 Oceania Queensland COMPLETE NaN 1360 73 NaN http://images.acmesports.sports/Smart+watch Smart watch 327.75 0 1/16/2018 11:45 Standard Class
4 PAYMENT 2 4 1.342100e+09 2.982500e+02 Advance shipping 0 73 Sporting Goods Caguas Puerto Rico XXXXXXXXX Orli 19489 Hendricks XXXXXXXXX Corporate PR 8671 Iron Anchor Corners 725.0 2 Fitness 1.825.376.892 -6.603.704.834 Pacific Asia Townsville Australia 19489 1/13/2018 11:24 75936 1360 29.5 0.09 179251 327.75 0.449999988 1 327.75 298.25 1.342.100.067 Oceania Queensland PENDING_PAYMENT NaN 1360 73 NaN http://images.acmesports.sports/Smart+watch Smart watch 327.75 0 1/15/2018 11:24 Standard Class
In [3]:
df_1.shape
Out[3]:
(180519, 53)

Operaciones sobr el conjunto de datos

In [4]:
# filtrar filas
# Primero, filtramos el DataFrame para incluir solo los datos de Argentina
#df_1 = df[df['Order Country'] == 'Argentina','Brasil','Mexico']
df = df_1[df_1['Order Country'].isin(['Argentina', 'Brasil', 'Mexico'])]
#df= df_1[(df['Order Country'] == 'Argentina') | (df_1['Order Country'] == 'Brasil') | (df_1['Order Country'] == 'Mexico')]
In [5]:
df.head()
Out[5]:
Type Days for shipping (real) Days for shipment (scheduled) Benefit per order Sales per customer Delivery Status Late_delivery_risk Category Id Category Name Customer City Customer Country Customer Email Customer Fname Customer Id Customer Lname Customer Password Customer Segment Customer State Customer Street Customer Zipcode Department Id Department Name Latitude Longitude Market Order City Order Country Order Customer Id order date (DateOrders) Order Id Order Item Cardprod Id Order Item Discount Order Item Discount Rate Order Item Id Order Item Product Price Order Item Profit Ratio Order Item Quantity Sales Order Item Total Order Profit Per Order Order Region Order State Order Status Order Zipcode Product Card Id Product Category Id Product Description Product Image Product Name Product Price Product Status shipping date (DateOrders) Shipping Mode
84 PAYMENT 4 2 2.347000e+09 144.0 Late delivery 1 24 Women's Apparel Caguas Puerto Rico XXXXXXXXX Mary 8541 Smith XXXXXXXXX Home Office PR 5700 Little Circle 725.0 5 Golf 1.829.609.299 -6.637.050.629 LATAM Juazeiro Brasil 8541 4/11/2017 15:49 56973 502 6 0.04 142502 50 0.159999996 3 150 144 2.346.999.931 South America Bahía PENDING_PAYMENT NaN 502 24 NaN http://images.acmesports.sports/Nike+Men%27s+D... Nike Men's Dri-FIT Victory Golf Polo 50 0 4/15/2017 15:49 Second Class
86 PAYMENT 6 2 4.366000e+09 139.5 Late delivery 1 24 Women's Apparel Caguas Puerto Rico XXXXXXXXX Mary 3752 Vega XXXXXXXXX Home Office PR 7840 Umber Sky Villas 725.0 5 Golf 182.105.732 -6.637.058.258 LATAM Mexico City Mexico 3752 3/16/2017 2:54 55155 502 10.5 0.07 137932 50 0.310000002 3 150 139.5 4.365.999.985 Central America Distrito Federal PENDING_PAYMENT NaN 502 24 NaN http://images.acmesports.sports/Nike+Men%27s+D... Nike Men's Dri-FIT Victory Golf Polo 50 0 3/22/2017 2:54 Second Class
87 PAYMENT 2 2 1.320000e+09 132.0 Shipping on time 0 24 Women's Apparel Caguas Puerto Rico XXXXXXXXX Wayne 4673 Hodges XXXXXXXXX Home Office PR 7509 Iron Concession 725.0 5 Golf 1.820.111.656 -6.637.059.021 LATAM Tlaquepaque Mexico 4673 3/29/2015 10:33 5991 502 18 0.12 14921 50 0.100000001 3 150 132 1.319.999.981 Central America Jalisco PENDING_PAYMENT NaN 502 24 NaN http://images.acmesports.sports/Nike+Men%27s+D... Nike Men's Dri-FIT Victory Golf Polo 50 0 3/31/2015 10:33 Second Class
88 PAYMENT 4 2 4.620000e+09 132.0 Late delivery 1 24 Women's Apparel Caguas Puerto Rico XXXXXXXXX Mary 5367 Mccormick XXXXXXXXX Home Office PR 2199 Silver Autumn Key 725.0 5 Golf 1.821.469.116 -6.637.051.392 LATAM Puebla Mexico 5367 2/3/2015 00:28 2263 502 18 0.12 5671 50 0.349999994 3 150 132 4.620.000.076 Central America Puebla PENDING_PAYMENT NaN 502 24 NaN http://images.acmesports.sports/Nike+Men%27s+D... Nike Men's Dri-FIT Victory Golf Polo 50 0 2/7/2015 00:28 Second Class
89 PAYMENT 4 2 1.044000e+09 130.5 Late delivery 1 24 Women's Apparel Caguas Puerto Rico XXXXXXXXX Mary 5367 Mccormick XXXXXXXXX Home Office PR 2199 Silver Autumn Key 725.0 5 Golf 1.821.469.116 -6.637.051.392 LATAM Puebla Mexico 5367 2/3/2015 00:28 2263 502 19.5 0.13 5669 50 0.079999998 3 150 130.5 1.043.999.958 Central America Puebla PENDING_PAYMENT NaN 502 24 NaN http://images.acmesports.sports/Nike+Men%27s+D... Nike Men's Dri-FIT Victory Golf Polo 50 0 2/7/2015 00:28 Second Class
In [6]:
df.tail()
Out[6]:
Type Days for shipping (real) Days for shipment (scheduled) Benefit per order Sales per customer Delivery Status Late_delivery_risk Category Id Category Name Customer City Customer Country Customer Email Customer Fname Customer Id Customer Lname Customer Password Customer Segment Customer State Customer Street Customer Zipcode Department Id Department Name Latitude Longitude Market Order City Order Country Order Customer Id order date (DateOrders) Order Id Order Item Cardprod Id Order Item Discount Order Item Discount Rate Order Item Id Order Item Product Price Order Item Profit Ratio Order Item Quantity Sales Order Item Total Order Profit Per Order Order Region Order State Order Status Order Zipcode Product Card Id Product Category Id Product Description Product Image Product Name Product Price Product Status shipping date (DateOrders) Shipping Mode
179618 TRANSFER 6 4 1.337500e+02 2.729500e+09 Late delivery 1 17 Cleats Caguas Puerto Rico XXXXXXXXX Brenda 12354 Wells XXXXXXXXX Consumer PR 3762 Amber Estates 725.0 4 Apparel 1.823.072.052 -6.637.063.599 LATAM Goiânia Brasil 12354 4/18/2015 13:41 7370 365 27 0.09 18457 5.999.000.168 0.49000001 5 2.999.500.122 2.729.500.122 133.75 South America Goiás PENDING NaN 365 17 NaN http://images.acmesports.sports/Perfect+Fitnes... Perfect Fitness Perfect Rip Deck 5.999.000.168 0 4/24/2015 13:41 Standard Class
179621 TRANSFER 3 4 -2.610000e+09 2.609600e+09 Advance shipping 0 17 Cleats Juana Diaz Puerto Rico XXXXXXXXX Mary 10344 Smith XXXXXXXXX Consumer PR 2839 Grand Timber Canyon 795.0 4 Apparel 1.805.199.051 -6.650.184.631 LATAM Villahermosa Mexico 10344 5/16/2017 21:33 59387 365 3.899.000.168 0.13 148676 5.999.000.168 -0.100000001 5 2.999.500.122 2.609.599.915 -2.610.000.038 Central America Tabasco PENDING NaN 365 17 NaN http://images.acmesports.sports/Perfect+Fitnes... Perfect Fitness Perfect Rip Deck 5.999.000.168 0 5/19/2017 21:33 Standard Class
179623 TRANSFER 2 4 1.174300e+09 2.609600e+09 Advance shipping 0 17 Cleats Caguas Puerto Rico XXXXXXXXX Mary 8917 Smith XXXXXXXXX Consumer PR 4992 Jagged Forest Subdivision 725.0 4 Apparel 1.822.487.068 -6.637.052.155 LATAM Barueri Brasil 8917 4/13/2017 14:25 57106 365 3.899.000.168 0.13 142839 5.999.000.168 0.449999988 5 2.999.500.122 2.609.599.915 1.174.300.003 South America São Paulo PENDING NaN 365 17 NaN http://images.acmesports.sports/Perfect+Fitnes... Perfect Fitness Perfect Rip Deck 5.999.000.168 0 4/15/2017 14:25 Standard Class
179624 TRANSFER 3 4 4.844000e+09 2.549600e+09 Advance shipping 0 17 Cleats Caguas Puerto Rico XXXXXXXXX Mary 9204 Harris XXXXXXXXX Consumer PR 8713 Quaking Abbey 725.0 4 Apparel 1.828.453.636 -6.637.060.547 LATAM Maceió Brasil 9204 5/27/2017 16:48 60127 365 4.499.000.168 0.15 150462 5.999.000.168 0.189999998 5 2.999.500.122 2.549.600.067 4.843.999.863 South America Alagoas PENDING NaN 365 17 NaN http://images.acmesports.sports/Perfect+Fitnes... Perfect Fitness Perfect Rip Deck 5.999.000.168 0 5/30/2017 16:48 Standard Class
179628 TRANSFER 3 4 6.749000e+09 2.249600e+09 Advance shipping 0 17 Cleats Caguas Puerto Rico XXXXXXXXX Jerry 7024 Smith XXXXXXXXX Consumer PR 5149 Rocky Pine Moor 725.0 4 Apparel 1.822.907.066 -6.637.058.258 LATAM Mexico City Mexico 7024 5/19/2017 3:51 59542 365 7.498.999.786 0.25 149029 5.999.000.168 0.300000012 5 2.999.500.122 2.249.600.067 6.748.999.786 Central America Distrito Federal PENDING NaN 365 17 NaN http://images.acmesports.sports/Perfect+Fitnes... Perfect Fitness Perfect Rip Deck 5.999.000.168 0 5/22/2017 3:51 Standard Class
In [7]:
df.shape
Out[7]:
(23090, 53)

Información general del DataFrame ---tipo de datos---

Información general del DataFrame: se obtiene la información general, como el número de filas y columnas, los tipos de datos y si hay valores nulos:¶

In [8]:
df.info()
<class 'pandas.core.frame.DataFrame'>
Index: 23090 entries, 84 to 179628
Data columns (total 53 columns):
 #   Column                         Non-Null Count  Dtype  
---  ------                         --------------  -----  
 0   Type                           23090 non-null  object 
 1   Days for shipping (real)       23090 non-null  int64  
 2   Days for shipment (scheduled)  23090 non-null  int64  
 3   Benefit per order              23090 non-null  float64
 4   Sales per customer             23090 non-null  float64
 5   Delivery Status                23090 non-null  object 
 6   Late_delivery_risk             23090 non-null  int64  
 7   Category Id                    23090 non-null  int64  
 8   Category Name                  23090 non-null  object 
 9   Customer City                  23090 non-null  object 
 10  Customer Country               23090 non-null  object 
 11  Customer Email                 23090 non-null  object 
 12  Customer Fname                 23090 non-null  object 
 13  Customer Id                    23090 non-null  int64  
 14  Customer Lname                 23090 non-null  object 
 15  Customer Password              23090 non-null  object 
 16  Customer Segment               23090 non-null  object 
 17  Customer State                 23090 non-null  object 
 18  Customer Street                23090 non-null  object 
 19  Customer Zipcode               23090 non-null  float64
 20  Department Id                  23090 non-null  int64  
 21  Department Name                23090 non-null  object 
 22  Latitude                       23090 non-null  object 
 23  Longitude                      23090 non-null  object 
 24  Market                         23090 non-null  object 
 25  Order City                     23090 non-null  object 
 26  Order Country                  23090 non-null  object 
 27  Order Customer Id              23090 non-null  int64  
 28  order date (DateOrders)        23090 non-null  object 
 29  Order Id                       23090 non-null  int64  
 30  Order Item Cardprod Id         23090 non-null  int64  
 31  Order Item Discount            23090 non-null  object 
 32  Order Item Discount Rate       23090 non-null  float64
 33  Order Item Id                  23090 non-null  int64  
 34  Order Item Product Price       23090 non-null  object 
 35  Order Item Profit Ratio        23090 non-null  object 
 36  Order Item Quantity            23090 non-null  int64  
 37  Sales                          23090 non-null  object 
 38  Order Item Total               23090 non-null  object 
 39  Order Profit Per Order         23090 non-null  object 
 40  Order Region                   23090 non-null  object 
 41  Order State                    23090 non-null  object 
 42  Order Status                   23090 non-null  object 
 43  Order Zipcode                  0 non-null      float64
 44  Product Card Id                23090 non-null  int64  
 45  Product Category Id            23090 non-null  int64  
 46  Product Description            0 non-null      float64
 47  Product Image                  23090 non-null  object 
 48  Product Name                   23090 non-null  object 
 49  Product Price                  23090 non-null  object 
 50  Product Status                 23090 non-null  int64  
 51  shipping date (DateOrders)     23090 non-null  object 
 52  Shipping Mode                  23090 non-null  object 
dtypes: float64(6), int64(14), object(33)
memory usage: 9.5+ MB

La informacion general indica que los datos en las columnas del tipo "object", significa que son un cadena de texto u otro tipo no numerico

In [9]:
#product description y Order Zipcode esta en blanco toda la columna
# Product state es "0" para toda la columna

Verificar si existen filas duplicadas o espacios vacios.

In [10]:
# verificar filas duplicadas
duplicados=df[df.duplicated()]
if duplicados.empty:
    print("No hay filas duplicadas en el DataFrame.")
else:
    print("Las siguientes filas están duplicadas:")
    print(duplicados)
No hay filas duplicadas en el DataFrame.
In [11]:
# verificar espacios vacios
hay_vacios = df.isna().any().any()

if hay_vacios:
    print("El DataFrame contiene valores vacíos.")
else:
    print("El DataFrame no contiene valores vacíos.")
El DataFrame contiene valores vacíos.
In [12]:
# quitar columnas vacias 
df = df.drop(['Product Description', 'Order Zipcode', 'Product Status'], axis=1)
In [13]:
# quitar columnas vacias 
In [14]:
#ELIMINAMOS FILAS DEL DATAFRAME QUE NO USAMOS.
columnas_a_eliminar = ['Sales per customer','Category Id','Customer City','Customer Email','Customer Fname','Customer Lname',
'Customer Password','Customer State','Customer Street','Customer Zipcode','Department Id','Department Name','Latitude',
'Longitude','Market','Order City','Order Customer Id','Order Item Cardprod Id','Order Item Discount', 'Order Item Discount Rate',
'Order Item Profit Ratio','Product Image']

df = df.drop(columns=columnas_a_eliminar)

cinco ultimas filas

número de filas y columnas

In [15]:
df.shape
Out[15]:
(23090, 28)

nombres de columnas

In [16]:
df.columns
Out[16]:
Index(['Type', 'Days for shipping (real)', 'Days for shipment (scheduled)', 'Benefit per order', 'Delivery Status', 'Late_delivery_risk', 'Category Name', 'Customer Country', 'Customer Id', 'Customer Segment', 'Order Country', 'order date (DateOrders)', 'Order Id', 'Order Item Id', 'Order Item Product Price', 'Order Item Quantity', 'Sales', 'Order Item Total', 'Order Profit Per Order', 'Order Region', 'Order State', 'Order Status', 'Product Card Id', 'Product Category Id', 'Product Name', 'Product Price', 'shipping date (DateOrders)', 'Shipping Mode'], dtype='object')
In [ ]:
 
In [17]:
# trabajo previo
# 1- filtrar el set de datos original por pais para abarcar solo argentina, brasil y mexico
# 2- quitar columnas

#EL DATAFRAME RESULTANTE DE ESTE PROCESO SE EMPLEA PARA TRABAJAR
In [18]:
#CAMBIAR LAS COLUMNAS A ESPAÑOL
#// prueba para cambiar los valores de las columnas a español
df_espanol=df
In [19]:
#renombro la columna porque tiene espacios
df_espanol.rename(columns={'Category Name':'Categoria',
                           'Type':'Pago'
                           ,'Days for shipping (real)':'DiasEnvio(Real)'
                           , 'Days for shipment (scheduled)':'DiasEnvio(Programado)'
                           , 'Benefit per order':'BeneficioPorPedido'
                           , 'Delivery Status':'EstadoEntrega'
                           , 'Late_delivery_risk':'RiesgoEntregaTardia'
                           , 'Category Name':'Categoria'
                           , 'Customer Country':'PaisCliente'
                           , 'Customer Id':'IDCliente'
                           , 'Customer Segment':'SegmentoCliente'
                           , 'Order Country':'PaisPedido'
                           , 'order date (DateOrders)':'FechaPedido'
                           , 'Order Id':'IDPedido'
                           , 'Order Item Id':'IDArticuloPedido'
                           , 'Order Item Product Price':'PrecioArticuloPedido'
                           , 'Order Item Quantity':'CantidadArticulosPedido'
                           , 'Sales':'Ventas'
                           , 'Order Item Total':'TotalArticulosPedido'
                           , 'Order Profit Per Order':'GananciaPorPedido'
                           , 'Order Region':'RegionPedido'
                           , 'Order State':'DestinoPedido'
                           , 'Order Status':'EstadoPedido'
                           , 'Product Card Id':'IDProducto'
                           , 'Product Category Id':'CategoriaProducto'
                           , 'Product Name':'NombreProducto'
                           , 'Product Price':'PrecioProducto'
                           , 'shipping date (DateOrders)':'FechaEnvio'
                           , 'Shipping Mode':'ModoEnvio'                                
                          
                          },inplace=True)
In [20]:
df_espanol.info()
<class 'pandas.core.frame.DataFrame'>
Index: 23090 entries, 84 to 179628
Data columns (total 28 columns):
 #   Column                   Non-Null Count  Dtype  
---  ------                   --------------  -----  
 0   Pago                     23090 non-null  object 
 1   DiasEnvio(Real)          23090 non-null  int64  
 2   DiasEnvio(Programado)    23090 non-null  int64  
 3   BeneficioPorPedido       23090 non-null  float64
 4   EstadoEntrega            23090 non-null  object 
 5   RiesgoEntregaTardia      23090 non-null  int64  
 6   Categoria                23090 non-null  object 
 7   PaisCliente              23090 non-null  object 
 8   IDCliente                23090 non-null  int64  
 9   SegmentoCliente          23090 non-null  object 
 10  PaisPedido               23090 non-null  object 
 11  FechaPedido              23090 non-null  object 
 12  IDPedido                 23090 non-null  int64  
 13  IDArticuloPedido         23090 non-null  int64  
 14  PrecioArticuloPedido     23090 non-null  object 
 15  CantidadArticulosPedido  23090 non-null  int64  
 16  Ventas                   23090 non-null  object 
 17  TotalArticulosPedido     23090 non-null  object 
 18  GananciaPorPedido        23090 non-null  object 
 19  RegionPedido             23090 non-null  object 
 20  DestinoPedido            23090 non-null  object 
 21  EstadoPedido             23090 non-null  object 
 22  IDProducto               23090 non-null  int64  
 23  CategoriaProducto        23090 non-null  int64  
 24  NombreProducto           23090 non-null  object 
 25  PrecioProducto           23090 non-null  object 
 26  FechaEnvio               23090 non-null  object 
 27  ModoEnvio                23090 non-null  object 
dtypes: float64(1), int64(9), object(18)
memory usage: 5.1+ MB

Conteo de valores únicos por columna:

In [21]:
df_espanol.nunique()
Out[21]:
Pago                           4
DiasEnvio(Real)                7
DiasEnvio(Programado)          4
BeneficioPorPedido          8792
EstadoEntrega                  4
RiesgoEntregaTardia            2
Categoria                     31
PaisCliente                    2
IDCliente                   5714
SegmentoCliente                3
PaisPedido                     3
FechaPedido                 7687
IDPedido                    7687
IDArticuloPedido           23090
PrecioArticuloPedido          50
CantidadArticulosPedido        5
Ventas                       164
TotalArticulosPedido        1575
GananciaPorPedido           8792
RegionPedido                   2
DestinoPedido                 76
EstadoPedido                   9
IDProducto                    87
CategoriaProducto             32
NombreProducto                87
PrecioProducto                50
FechaEnvio                  7582
ModoEnvio                      4
dtype: int64

Verificar si existen filas duplicadas o espacios vacios.

In [22]:
# verificar filas duplicadas
duplicados=df_espanol[df.duplicated()]
if duplicados.empty:
    print("No hay filas duplicadas en el DataFrame.")
else:
    print("Las siguientes filas están duplicadas:")
    print(duplicados)
No hay filas duplicadas en el DataFrame.
In [23]:
# verificar espacios vacios
hay_vacios = df_espanol.isna().any().any()

if hay_vacios:
    print("El DataFrame contiene valores vacíos.")
else:
    print("El DataFrame no contiene valores vacíos.")
El DataFrame no contiene valores vacíos.
In [24]:
# FIN DE LA PRIMERA PARTE: Exploración Inicial de Datos:
In [25]:
# 2 PARTE: ANALISIS UNIVARIADO
In [26]:
# VER LOS VALORES DE UNA VARIABLE 
df_espanol.Categoria.unique()
Out[26]:
array(["Women's Apparel", 'Shop By Sport', 'Electronics',
       'Baseball & Softball', 'Cardio Equipment', 'Boxing & MMA',
       'Cleats', "Girls' Apparel", 'Accessories', 'Golf Balls',
       'Trade-In', 'Hockey', 'Camping & Hiking', 'Fishing',
       "Men's Footwear", 'Soccer', 'Fitness Accessories',
       "Kids' Golf Clubs", 'Tennis & Racquet', 'Lacrosse',
       'Hunting & Shooting', 'As Seen on  TV!', 'Strength Training',
       'Golf Gloves', 'Golf Bags & Carts', 'Golf Shoes', 'Golf Apparel',
       "Women's Golf Clubs", "Men's Golf Clubs", 'Water Sports',
       'Indoor/Outdoor Games'], dtype=object)
In [27]:
df_espanol.Pago.unique()
Out[27]:
array(['PAYMENT', 'TRANSFER', 'DEBIT', 'CASH'], dtype=object)
In [28]:
df_espanol.ModoEnvio.unique()
Out[28]:
array(['Second Class', 'Standard Class', 'First Class', 'Same Day'],
      dtype=object)
In [29]:
df_espanol.EstadoEntrega.unique()
Out[29]:
array(['Late delivery', 'Shipping on time', 'Advance shipping',
       'Shipping canceled'], dtype=object)
In [30]:
df_espanol.EstadoEntrega.unique()
Out[30]:
array(['Late delivery', 'Shipping on time', 'Advance shipping',
       'Shipping canceled'], dtype=object)
In [31]:
#HASTA ACA ESTA TODO BIEN------------

Análisis Univariado:

Distribución de Variables: Realizar un análisis de las variables individuales para entender su distribución. Utilizar histogramas, boxplots y estadísticas descriptivas (media, mediana, desviación estándar, etc.) para las variables numéricas. Para las variables categóricas, calcular frecuencias y proporciones.
Identificación de Outliers: Detectar posibles outliers en las variables numéricas utilizando técnicas como el análisis de boxplots o el cálculo del z-score.

In [32]:
#EXPLORAMOS LOS DATOS:
#Obtenemos estadísticas descriptivas sobre las columnas numéricas del conjunto de datos:
In [33]:
df.describe()
Out[33]:
DiasEnvio(Real) DiasEnvio(Programado) BeneficioPorPedido RiesgoEntregaTardia IDCliente IDPedido IDArticuloPedido CantidadArticulosPedido IDProducto CategoriaProducto
count 23090.000000 23090.000000 2.309000e+04 23090.000000 23090.000000 23090.000000 23090.000000 23090.000000 23090.000000 23090.000000
mean 3.532395 2.957687 2.337699e+09 0.544651 6239.185881 31248.316544 78148.127934 2.182763 664.433911 30.279385
std 1.628313 1.354260 3.819456e+09 0.498013 3574.207795 25789.096724 64514.324265 1.471115 309.893562 13.687618
min 0.000000 0.000000 -9.984000e+09 0.000000 3.000000 1.000000 1.000000 1.000000 19.000000 2.000000
25% 2.000000 2.000000 7.050000e+01 0.000000 3184.000000 5498.000000 13714.250000 1.000000 403.000000 18.000000
50% 3.000000 4.000000 1.966500e+09 1.000000 6194.000000 51386.000000 128407.500000 1.000000 627.000000 29.000000
75% 5.000000 4.000000 4.963000e+09 1.000000 9299.500000 56713.750000 141840.750000 3.000000 1004.000000 45.000000
max 6.000000 4.000000 9.999000e+09 1.000000 12434.000000 61584.000000 153996.000000 5.000000 1073.000000 48.000000
In [34]:
df_espanol.describe()
Out[34]:
DiasEnvio(Real) DiasEnvio(Programado) BeneficioPorPedido RiesgoEntregaTardia IDCliente IDPedido IDArticuloPedido CantidadArticulosPedido IDProducto CategoriaProducto
count 23090.000000 23090.000000 2.309000e+04 23090.000000 23090.000000 23090.000000 23090.000000 23090.000000 23090.000000 23090.000000
mean 3.532395 2.957687 2.337699e+09 0.544651 6239.185881 31248.316544 78148.127934 2.182763 664.433911 30.279385
std 1.628313 1.354260 3.819456e+09 0.498013 3574.207795 25789.096724 64514.324265 1.471115 309.893562 13.687618
min 0.000000 0.000000 -9.984000e+09 0.000000 3.000000 1.000000 1.000000 1.000000 19.000000 2.000000
25% 2.000000 2.000000 7.050000e+01 0.000000 3184.000000 5498.000000 13714.250000 1.000000 403.000000 18.000000
50% 3.000000 4.000000 1.966500e+09 1.000000 6194.000000 51386.000000 128407.500000 1.000000 627.000000 29.000000
75% 5.000000 4.000000 4.963000e+09 1.000000 9299.500000 56713.750000 141840.750000 3.000000 1004.000000 45.000000
max 6.000000 4.000000 9.999000e+09 1.000000 12434.000000 61584.000000 153996.000000 5.000000 1073.000000 48.000000
In [35]:
# Para cada COLUMNA NUMERICA DE INTERES calcular la mediana, MEDIA Y DESVIACION ESTANDAR
# EJEMPLO PARA Benefit per order Y PRECIO DE PRODUCTO
In [36]:
# el precio del producto tiene valores vacios...ademas hay que convertirlo porque esta en formato Object..a numerico para hacer calculos
In [37]:
import re
import pandas as pd

def clean_price(price_str):
    if pd.isna(price_str):
        return None
    
    # Convertir a string si no lo es
    price_str = str(price_str)
    
    # Eliminar espacios en blanco y caracteres no numéricos excepto punto y coma
    cleaned = re.sub(r'[^\d.,]', '', price_str)
    
    # Reemplazar coma por punto si hay más de un punto (asumiendo que la coma es el separador decimal)
    if cleaned.count('.') > 1 and ',' in cleaned:
        cleaned = cleaned.replace(',', '.')
    
    # Si hay más de un punto, asumimos que todos menos el último son separadores de miles
    parts = cleaned.split('.')
    if len(parts) > 2:
        integer_part = ''.join(parts[:-1])
        decimal_part = parts[-1]
        cleaned = f"{integer_part}.{decimal_part}"
    
    try:
        return float(cleaned)
    except ValueError:
        print(f"No se pudo convertir: {price_str}")
        return None

# Aplicar la función a la columna 'Product Price' y mostrar los resultados
df_espanol['Clean Price'] = df['PrecioProducto'].apply(clean_price)

# Mostrar filas donde la limpieza falló
failed_conversions = df[df['PrecioProducto'].isna()]
print("Filas donde la conversión falló:")
print(failed_conversions[['PrecioProducto', 'Clean Price']])

# Calcular la mediana de los precios limpios
median_prices = df.groupby('Categoria')['Clean Price'].median()
print("\nMediana de precios de productos segun categoria:")
print(median_prices)

# Calcular la media de los precios limpios
media_prices = df.groupby('Categoria')['Clean Price'].mean()
print("\nMedia de precios  de productos segun categoria:")
print(media_prices)
# Calcular la desviacion estandar de los precios limpios
std_prices = df.groupby('Categoria')['Clean Price'].std()
print("\nDesviacion estandar de productos segun categoria:")
print(std_prices)

# Mostrar estadísticas de la columna de precios limpios
print("\nEstadísticas de la columna de precio de productos:")
print(df['Clean Price'].describe())
Filas donde la conversión falló:
Empty DataFrame
Columns: [PrecioProducto, Clean Price]
Index: []

Mediana de precios de productos segun categoria:
Categoria
Accessories             2498999.977
As Seen on  TV!         9998999.786
Baseball & Softball     3499000.168
Boxing & MMA            8998999.786
Camping & Hiking         299980.011
Cardio Equipment        9998999.786
Cleats                  5999000.168
Electronics             3198999.977
Fishing                  399980.011
Fitness Accessories     3499000.168
Girls' Apparel               70.000
Golf Apparel            1998999.977
Golf Bags & Carts       1699900.055
Golf Balls              1798999.977
Golf Gloves             3999000.168
Golf Shoes                   80.000
Hockey                       22.000
Hunting & Shooting      2998999.977
Indoor/Outdoor Games    4997999.954
Kids' Golf Clubs        1999900.055
Lacrosse                2498999.977
Men's Footwear          1299900.055
Men's Golf Clubs        1324900.055
Shop By Sport           3999000.168
Soccer                  7998999.786
Strength Training           189.000
Tennis & Racquet        4499000.168
Trade-In                1598999.977
Water Sports            1999900.055
Women's Apparel              50.000
Women's Golf Clubs      7998999.786
Name: Clean Price, dtype: float64

Media de precios  de productos segun categoria:
Categoria
Accessories             2.499000e+06
As Seen on  TV!         9.999000e+06
Baseball & Softball     4.362567e+06
Boxing & MMA            7.405708e+06
Camping & Hiking        2.999800e+05
Cardio Equipment        9.753777e+06
Cleats                  5.999000e+06
Electronics             3.986990e+06
Fishing                 3.999800e+05
Fitness Accessories     3.499000e+06
Girls' Apparel          1.312678e+06
Golf Apparel            1.721369e+06
Golf Bags & Carts       1.699900e+06
Golf Balls              1.774500e+06
Golf Gloves             5.901723e+06
Golf Shoes              8.122826e+01
Hockey                  2.342308e+01
Hunting & Shooting      2.346087e+06
Indoor/Outdoor Games    4.998000e+06
Kids' Golf Clubs        5.153402e+06
Lacrosse                4.604263e+06
Men's Footwear          1.299900e+06
Men's Golf Clubs        2.857235e+06
Shop By Sport           3.879653e+06
Soccer                  5.839288e+06
Strength Training       1.890000e+02
Tennis & Racquet        4.499000e+06
Trade-In                1.899081e+06
Water Sports            1.999900e+06
Women's Apparel         5.000000e+01
Women's Golf Clubs      6.459881e+06
Name: Clean Price, dtype: float64

Desviacion estandar de productos segun categoria:
Categoria
Accessories             0.000000e+00
As Seen on  TV!         0.000000e+00
Baseball & Softball     1.615250e+06
Boxing & MMA            1.902672e+06
Camping & Hiking        0.000000e+00
Cardio Equipment        1.547033e+06
Cleats                  0.000000e+00
Electronics             9.034617e+05
Fishing                 0.000000e+00
Fitness Accessories     0.000000e+00
Girls' Apparel          1.885016e+06
Golf Apparel            3.644281e+05
Golf Bags & Carts       0.000000e+00
Golf Balls              2.190655e+05
Golf Gloves             3.338846e+06
Golf Shoes              1.795299e+01
Hockey                  1.507722e+00
Hunting & Shooting      1.038113e+06
Indoor/Outdoor Games    0.000000e+00
Kids' Golf Clubs        4.335915e+06
Lacrosse                3.400022e+06
Men's Footwear          0.000000e+00
Men's Golf Clubs        3.413800e+06
Shop By Sport           6.421471e+05
Soccer                  3.213214e+06
Strength Training       0.000000e+00
Tennis & Racquet        0.000000e+00
Trade-In                3.393157e+05
Water Sports            0.000000e+00
Women's Apparel         0.000000e+00
Women's Golf Clubs      3.646446e+06
Name: Clean Price, dtype: float64

Estadísticas de la columna de precio de productos:
count    2.309000e+04
mean     3.035057e+06
std      2.934299e+06
min      2.200000e+01
25%      3.999800e+05
50%      1.999900e+06
75%      4.998000e+06
max      9.999000e+06
Name: Clean Price, dtype: float64
In [38]:
import re
import pandas as pd

def clean_Beneficio_por_pedido(benPP_str):
    if pd.isna(benPP_str):
        return None
    
    # Convertir a string si no lo es
    benPP_str = str(benPP_str)
    
    # Eliminar espacios en blanco y caracteres no numéricos excepto punto y coma
    cleaned = re.sub(r'[^\d.,]', '', benPP_str)
    
    # Reemplazar coma por punto si hay más de un punto (asumiendo que la coma es el separador decimal)
    if cleaned.count('.') > 1 and ',' in cleaned:
        cleaned = cleaned.replace(',', '.')
    
    # Si hay más de un punto, asumimos que todos menos el último son separadores de miles
    parts = cleaned.split('.')
    if len(parts) > 2:
        integer_part = ''.join(parts[:-1])
        decimal_part = parts[-1]
        cleaned = f"{integer_part}.{decimal_part}"
    
    try:
        return float(cleaned)
    except ValueError:
        print(f"No se pudo convertir: {benPP_str}")
        return None

# Aplicar la función a la columna 'Benefit per order' y mostrar los resultados
df['clean_Beneficio_por_pedido'] = df['BeneficioPorPedido'].apply(clean_Beneficio_por_pedido)

# Mostrar filas donde la limpieza falló
failed_conversions = df[df['clean_Beneficio_por_pedido'].isna()]
print("Filas donde la conversión falló:")
print(failed_conversions[['BeneficioPorPedido', 'clean_Beneficio_por_pedido']])

# Calcular la mediana de los precios limpios
median_prices = df.groupby('IDPedido')['clean_Beneficio_por_pedido'].median()
print("\nMediana de precios por producto:")
print(median_prices)

# Mostrar estadísticas de la columna de precios limpios
print("\nEstadísticas de la columna Beneficio por Pedido:")
print(df['clean_Beneficio_por_pedido'].describe())
Filas donde la conversión falló:
Empty DataFrame
Columns: [BeneficioPorPedido, clean_Beneficio_por_pedido]
Index: []

Mediana de precios por producto:
IDPedido
1        8.879000e+09
7        4.580000e+09
8        1.499750e+09
9        1.980000e+09
10       1.564000e+09
             ...     
61580    1.161900e+09
61581    5.390000e+09
61582    1.050000e+09
61583    2.910000e+09
61584    2.291000e+09
Name: clean_Beneficio_por_pedido, Length: 7687, dtype: float64

Estadísticas de la columna Beneficio por Pedido:
count    2.309000e+04
mean     3.543691e+09
std      2.737705e+09
min      0.000000e+00
25%      1.329900e+09
50%      2.886000e+09
75%      5.481000e+09
max      9.999000e+09
Name: clean_Beneficio_por_pedido, dtype: float64
In [39]:
#histogramas, boxplots
In [40]:
# dias de entrega real
conteo_productos = df_espanol['DiasEnvio(Real)'].value_counts()

# Crear un gráfico de barras
plt.figure(figsize=(12, 6))
conteo_productos.plot(kind='bar')
plt.xlabel('dias')
plt.ylabel('Frecuencia')
plt.title('dias de entrega')
plt.xticks(rotation=60)  # Rotar etiquetas del eje x para mayor legibilidad
plt.show()
In [41]:
dias_entrega_real=df_espanol.groupby(['DiasEnvio(Real)'])['IDPedido'].count().reset_index(name='Numero de Pedidos').sort_values(by= 'Numero de Pedidos', ascending= False)
fig=px.bar(dias_entrega_real, x='DiasEnvio(Real)', y='Numero de Pedidos'  , color='DiasEnvio(Real)',
      )
fig.show()
In [42]:
#dias de entrega programado
conteo_productos = df_espanol['DiasEnvio(Programado)'].value_counts()

# Crear un gráfico de barras
plt.figure(figsize=(12, 6))
conteo_productos.plot(kind='bar')
plt.xlabel('dias')
plt.ylabel('Frecuencia')
plt.title('dias de entrega')
plt.xticks(rotation=60)  # Rotar etiquetas del eje x para mayor legibilidad
plt.show()
In [43]:
dias_entrega_real=df_espanol.groupby(['DiasEnvio(Programado)'])['IDPedido'].count().reset_index(name='Numero de Pedidos').sort_values(by= 'Numero de Pedidos', ascending= False)
fig=px.bar(dias_entrega_real, x='DiasEnvio(Programado)', y='Numero de Pedidos'  , color='DiasEnvio(Programado)'
      )
fig.show()
In [44]:
#FRECUENCIA DE PRODUCTOS
#Contamos y graficamos la frecuencia de los PRODUCTOS (muestra cuántas veces aparece cada PRODUCTO en los datos):
    # Contar la frecuencia de cada producto
conteo_productos = df_espanol['NombreProducto'].value_counts()

# Crear un gráfico de barras
plt.figure(figsize=(12, 6))
conteo_productos.plot(kind='bar')
plt.xlabel('Producto')
plt.ylabel('Frecuencia')
plt.title('Frecuencia de producto')
plt.xticks(rotation=60)  # Rotar etiquetas del eje x para mayor legibilidad
plt.show()
In [45]:
dias_entrega_real=df_espanol.groupby(['NombreProducto'])['IDProducto'].count().reset_index(name='Numero de Pedidos').sort_values(by= 'Numero de Pedidos', ascending= False)
fig=px.bar(dias_entrega_real, x='NombreProducto', y='Numero de Pedidos'  , color='NombreProducto'
      )
fig.show()
In [46]:
#FRECUENCIA DE PRODUCTOS
#Contamos y graficamos la frecuencia de los PRODUCTOS (muestra cuántas veces aparece cada PRODUCTO en los datos):
    # Contar la frecuencia de cada producto
conteo_categorias = df_espanol['CategoriaProducto'].value_counts()

# Crear un gráfico de barras
plt.figure(figsize=(12, 6))
conteo_categorias.plot(kind='barh')
plt.xlabel('Categoria')
plt.ylabel('Frecuencia')
plt.title('Frecuencia de categoria')
plt.xticks(rotation=60)  # Rotar etiquetas del eje x para mayor legibilidad
plt.show()
In [47]:
dias_entrega_real=df_espanol.groupby(['CategoriaProducto'])['IDProducto'].count().reset_index(name='Numero de Pedidos').sort_values(by= 'Numero de Pedidos', ascending= False)
fig=px.bar(dias_entrega_real, x='CategoriaProducto', y='Numero de Pedidos'  , color='CategoriaProducto'
      )
fig.show()
In [48]:
dias_entrega_real=df_espanol.groupby(['Categoria'])['IDProducto'].count().reset_index(name='Numero de Pedidos').sort_values(by= 'Numero de Pedidos', ascending= False)
fig=px.bar(dias_entrega_real, x='Categoria', y='Numero de Pedidos'  , color='Categoria'
      )
fig.show()
In [49]:
#Agrupamos por categoria y creamos un gráfico de barras que muestra el recuento de productos para cada categoria.
df_espanol.groupby('Categoria').count()['NombreProducto'].plot(kind='bar')
Out[49]:
<Axes: xlabel='Categoria'>
In [50]:
dias_entrega_real=df_espanol.groupby(['Categoria'])['IDProducto'].count().reset_index(name='Numero de Pedidos').sort_values(by= 'Numero de Pedidos', ascending= False)
fig=px.bar(dias_entrega_real, x='Categoria', y='Numero de Pedidos'  , color='Categoria'
      )
fig.show()
In [66]:
#Ahora buscamos el categoria con mayor :
df_espanol.groupby('Categoria').count()['Ventas'].plot(kind='barh')
Out[66]:
<Axes: ylabel='Categoria'>
In [68]:
# Aplicar la función a la columna 'Benefit per order' y mostrar los resultados
df_espanol['Ventas'] = df_espanol['Ventas'].apply(clean_Beneficio_por_pedido)
#df_espanol = df_espanol.drop([']Ventas'], axis=1)
In [69]:
df_espanol['Ventas1'] = df_espanol['Ventas']/100000
In [70]:
dias_entrega_real=df_espanol.groupby(['Categoria'])['Ventas1'].sum().reset_index(name='Total ventas').sort_values(by= 'Total ventas', ascending= False)
fig=px.bar(dias_entrega_real, x='Categoria', y='Total ventas'  , color='Categoria'
      )
fig.show()

estado de las ordenes (segun pais) - se discrimina por el estado de la orden¶

In [71]:
df_espanol.info()
<class 'pandas.core.frame.DataFrame'>
Index: 23090 entries, 84 to 179628
Data columns (total 32 columns):
 #   Column                      Non-Null Count  Dtype  
---  ------                      --------------  -----  
 0   Pago                        23090 non-null  object 
 1   DiasEnvio(Real)             23090 non-null  int64  
 2   DiasEnvio(Programado)       23090 non-null  int64  
 3   BeneficioPorPedido          23090 non-null  float64
 4   EstadoEntrega               23090 non-null  object 
 5   RiesgoEntregaTardia         23090 non-null  int64  
 6   Categoria                   23090 non-null  object 
 7   PaisCliente                 23090 non-null  object 
 8   IDCliente                   23090 non-null  int64  
 9   SegmentoCliente             23090 non-null  object 
 10  PaisPedido                  23090 non-null  object 
 11  FechaPedido                 23090 non-null  object 
 12  IDPedido                    23090 non-null  int64  
 13  IDArticuloPedido            23090 non-null  int64  
 14  PrecioArticuloPedido        23090 non-null  object 
 15  CantidadArticulosPedido     23090 non-null  int64  
 16  Ventas                      23090 non-null  float64
 17  TotalArticulosPedido        23090 non-null  object 
 18  GananciaPorPedido           23090 non-null  object 
 19  RegionPedido                23090 non-null  object 
 20  DestinoPedido               23090 non-null  object 
 21  EstadoPedido                23090 non-null  object 
 22  IDProducto                  23090 non-null  int64  
 23  CategoriaProducto           23090 non-null  int64  
 24  NombreProducto              23090 non-null  object 
 25  PrecioProducto              23090 non-null  object 
 26  FechaEnvio                  23090 non-null  object 
 27  ModoEnvio                   23090 non-null  object 
 28  Clean Price                 23090 non-null  float64
 29  clean_Beneficio_por_pedido  23090 non-null  float64
 30  Customer_ID_STR             23090 non-null  object 
 31  Ventas1                     23090 non-null  float64
dtypes: float64(5), int64(9), object(18)
memory usage: 5.8+ MB
In [72]:
data_delivery_status_region=df_espanol.groupby(['EstadoPedido', 'PaisPedido'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_delivery_status_region, x='EstadoPedido', y='Number of Orders'  , color='PaisPedido',
      )
fig.show()

estado de las ordenes segun region - discriminado por estado de las ordenes

In [73]:
data_delivery_status_region=df_espanol.groupby(['EstadoPedido', 'RegionPedido'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_delivery_status_region, x='EstadoPedido', y='Number of Orders'  , color='RegionPedido',
      )
fig.show()
In [74]:
data_delivery_status_region=df_espanol.groupby(['EstadoPedido', 'PaisCliente'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_delivery_status_region, x='EstadoPedido', y='Number of Orders'  , color='PaisCliente',
      )
fig.show()

ESTO NO VA, PORQUE SE SACO LA CIUDAD............estado de las ordenes segun el codigo de estado

In [75]:
data_delivery_status_region=df_espanol.groupby(['EstadoEntrega', 'PaisPedido'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_delivery_status_region, x='EstadoEntrega', y='Number of Orders'  , color='PaisPedido',
      )
fig.show()
In [76]:
data_delivery_status_region=df_espanol.groupby(['EstadoEntrega', 'RegionPedido'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_delivery_status_region, x='EstadoEntrega', y='Number of Orders'  , color='RegionPedido',
      )
fig.show()

son iguales porque hay solo un pais por region

In [77]:
data_delivery_status_region=df_espanol.groupby(['EstadoEntrega', 'PaisCliente'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_delivery_status_region, x='EstadoEntrega', y='Number of Orders'  , color='PaisCliente',
      )
fig.show()

solo para argentina*

In [78]:
# Primero, filtramos el DataFrame para incluir solo los datos de Argentina
df_argentina = df_espanol[df_espanol['PaisPedido'] == 'Argentina']

# Ahora realizamos el agrupamiento solo con los datos de Argentina
data_delivery_status_argentina = df_argentina.groupby('EstadoEntrega')['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by='Number of Orders', ascending=False)

# Creamos el gráfico de barras
fig = px.bar(data_delivery_status_argentina,
             x='EstadoEntrega',
             y='Number of Orders',
             title='Delivery Status for Orders in Argentina')

# Mostramos el gráfico
fig.show()
In [79]:
#solo para cordoba
# Primero, filtramos el DataFrame para incluir solo los datos de Argentina
df_argentina = df_espanol[df_espanol['PaisCliente'] == 'Puerto Rico']

# Ahora realizamos el agrupamiento solo con los datos de Argentina
data_delivery_status_argentina = df_argentina.groupby('EstadoEntrega')['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by='Number of Orders', ascending=False)

# Creamos el gráfico de barras
fig = px.bar(data_delivery_status_argentina,
             x='EstadoEntrega',
             y='Number of Orders',
             title='Estado de los pedidos que iran a Puerto Rico')

# Mostramos el gráfico
fig.show()

los principales 20 clientes segun la cantidad de pedidos¶

In [80]:
df_espanol['Customer_ID_STR']=df_espanol['IDCliente'].astype(str)

data_customers=df_espanol.groupby(['Customer_ID_STR'])['IDCliente'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_customers.head(20),x='Number of Orders', y='Customer_ID_STR' , color='Number of Orders'      )
fig.show()

20 principales clientes segun la cantidad de pedidos de argentina

In [81]:
#solo para cordoba
# Primero, filtramos el DataFrame para incluir solo los datos de Argentina
df_argentina = df_espanol[df_espanol['PaisPedido'] == 'Argentina']
data_customers=df_argentina.groupby(['Customer_ID_STR'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_customers.head(20),x='Number of Orders', y='Customer_ID_STR' , color='Number of Orders'      )
fig.show()

20 principales clientes segun las ganancias de todos los pedidos¶

----RECORDAR CAMBIAR "'CUSOTMER_ID_STR' EN TODOS ESTOS GRAFICOS, PONER UN NOMBRE APROPIADO"

In [84]:
#df_espanol.info()
In [85]:
df_espanol['Customer_ID_STR']=df_espanol['IDCliente'].astype(str)

data_customers_profit=df_espanol.groupby(['Customer_ID_STR'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
fig=px.bar(data_customers_profit.head(20),x='Ventas1', y='Customer_ID_STR' , color='Ventas1'      )
fig.show()

#ACLARAR QUE LOS VALORES ESTAN DIVIDIDOS POR MILLONES

segmento de cliente¶

In [86]:
#Customer Segments
data_Customer_Segment=df_espanol.groupby(['SegmentoCliente'])['IDCliente'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.pie(data_Customer_Segment, values='Number of Orders', names= 'SegmentoCliente' , title= 'Number of Orders of different Customer Segments',
       width=600 , height=600 , color_discrete_sequence = px.colors.qualitative.D3)
fig.show()
In [87]:
#Customer Segments de cordoba
df_argentina = df_espanol[df_espanol['RegionPedido'] == 'South America']

data_Customer_Segment=df_argentina.groupby(['SegmentoCliente'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
px.pie(data_Customer_Segment, values='Number of Orders', names= 'SegmentoCliente' , title= 'Number of Orders of different Customer Segments',
       width=600 , height=600 , color_discrete_sequence = ["red", "green", "blue", "goldenrod", "magenta"])
In [88]:
#Customer Segments de cordoba
df_argentina = df_espanol[df_espanol['RegionPedido'] == 'Central America']

data_Customer_Segment=df_argentina.groupby(['SegmentoCliente'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
px.pie(data_Customer_Segment, values='Number of Orders', names= 'SegmentoCliente' , title= 'Number of Orders of different Customer Segments',
       width=600 , height=600 , color_discrete_sequence = px.colors.qualitative.G10)
In [89]:
#BUSCAR LAS COMBINACIONES DE COLORES QUE QUEDEN PAREJAS...........NO MUY DISTINTAS

cagtegoria¶

In [90]:
#Categorias
data_Category_Name=df_espanol.groupby(['Categoria'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= True)
px.bar(data_Category_Name, x='Number of Orders',y = 'Categoria',color ='Number of Orders')

nombres de categorias para argentina

In [91]:
df_argentina = df_espanol[df_espanol['PaisPedido'] == 'Argentina']
data_Category_Name=df_argentina.groupby(['Categoria'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= True)
px.bar(data_Category_Name, x='Number of Orders',y = 'Categoria',color ='Number of Orders')

caracteristicas geografica¶

In [92]:
data_Region=df_espanol.groupby(['RegionPedido'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= True)
px.bar(data_Region, x='Number of Orders',y = 'RegionPedido',color ='Number of Orders')
In [93]:
data_countries=df_espanol.groupby(['PaisPedido'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= True)
px.bar(data_countries.head(20), x='Number of Orders',y = 'PaisPedido',color ='Number of Orders')
In [94]:
#FALTA SUMAR LAS VENTAS POR PAIS
#-----notar la escala es distinta, ver como se interpreta



data_countries=df_espanol.groupby(['PaisPedido'])['Ventas1'].sum().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= True)
px.bar(data_countries.head(20), x='Number of Orders',y = 'PaisPedido',color ='Number of Orders')
In [107]:
df_geo=df_espanol.groupby([ 'RegionPedido', 'PaisPedido'])['Ventas1'].sum().reset_index(name='Ventas').sort_values(by= 'Ventas', ascending= False)

df_geo
Out[107]:
RegionPedido PaisPedido Ventas
0 Central America Mexico 282077.461240
2 South America Brasil 170193.677838
1 South America Argentina 41405.607661
In [109]:
import pandas as pd
import plotly.express as px

# Asumiendo que ya tienes tu DataFrame 'df_geo'

# Crear el gráfico de coropletas
fig = px.choropleth(df_geo,
                    locationmode='country names',
                    locations='PaisPedido',
                    color='Ventas',
                    hover_name='PaisPedido',
                    color_continuous_scale=px.colors.sequential.Plasma)

# Ajustar el diseño para una mejor visualización
fig.update_layout(
    title_text='Mapa de Ganancias por País',
    geo=dict(
        showframe=False,
        showcoastlines=True,
        projection_type='equirectangular'
    )
)

# Mostrar el gráfico
fig.show()
In [110]:
df_espanol.PaisPedido.unique()
Out[110]:
array(['Brasil', 'Mexico', 'Argentina'], dtype=object)
In [111]:
# Ver si incluir si...el mapa no carga brasil
df_geo=df_espanol.groupby([ 'RegionPedido', 'PaisPedido'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)

px.pie(df_geo, values='Ventas1', names= 'PaisPedido' , title= 'Number of Orders of different Customer Segments',
       width=600 , height=600 , color_discrete_sequence = px.colors.qualitative.G10)

analisis de ventas¶

In [112]:
#HASTA ACA BIEN, SOLO HAY QUE VER QUE GRAFICOS QUEDAN Y CAMBIAR VARIABLES Y TITULOS DESCRIPTIVOS
In [119]:
# Asumiendo que tu DataFrame se llama 'df'

# 1. Verificar el tipo de datos actual y mostrar algunos ejemplos
print("Tipo de datos original de 'Ventas':", df_espanol['Ventas'].dtype)
print("\nEjemplos de valores en 'Ventas':")
print(df_espanol['Ventas'].head())

# 2. Función para convertir strings con formato europeo a float
def euro_to_float(value):
    # Reemplazar el punto por nada (eliminar separador de miles)
    # y la coma por punto (para decimales si los hubiera)
    return float(value.replace('.', '').replace(',', '.'))

# 3. Aplicar la conversión a la columna 'Sales'
df_espanol['Ventas1'] = df_espanol['Ventas'].apply(euro_to_float)

# 4. Crear la nueva columna 'Sales_Reduced'
df_espanol['Sales_Reduced'] = df_espanol['Ventas'] / 10000

#Order Country
#df['Sales_Reduced'] = df['Sales'] / 10000
Tipo de datos original de 'Ventas': float64

Ejemplos de valores en 'Ventas':
84    150.0
86    150.0
87    150.0
88    150.0
89    150.0
Name: Ventas, dtype: float64
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[119], line 15
     12     return float(value.replace('.', '').replace(',', '.'))
     14 # 3. Aplicar la conversión a la columna 'Sales'
---> 15 df_espanol['Ventas1'] = df_espanol['Ventas'].apply(euro_to_float)
     17 # 4. Crear la nueva columna 'Sales_Reduced'
     18 df_espanol['Sales_Reduced'] = df_espanol['Ventas'] / 10000

File ~\anaconda3\lib\site-packages\pandas\core\series.py:4924, in Series.apply(self, func, convert_dtype, args, by_row, **kwargs)
   4789 def apply(
   4790     self,
   4791     func: AggFuncType,
   (...)
   4796     **kwargs,
   4797 ) -> DataFrame | Series:
   4798     """
   4799     Invoke function on values of Series.
   4800 
   (...)
   4915     dtype: float64
   4916     """
   4917     return SeriesApply(
   4918         self,
   4919         func,
   4920         convert_dtype=convert_dtype,
   4921         by_row=by_row,
   4922         args=args,
   4923         kwargs=kwargs,
-> 4924     ).apply()

File ~\anaconda3\lib\site-packages\pandas\core\apply.py:1427, in SeriesApply.apply(self)
   1424     return self.apply_compat()
   1426 # self.func is Callable
-> 1427 return self.apply_standard()

File ~\anaconda3\lib\site-packages\pandas\core\apply.py:1507, in SeriesApply.apply_standard(self)
   1501 # row-wise access
   1502 # apply doesn't have a `na_action` keyword and for backward compat reasons
   1503 # we need to give `na_action="ignore"` for categorical data.
   1504 # TODO: remove the `na_action="ignore"` when that default has been changed in
   1505 #  Categorical (GH51645).
   1506 action = "ignore" if isinstance(obj.dtype, CategoricalDtype) else None
-> 1507 mapped = obj._map_values(
   1508     mapper=curried, na_action=action, convert=self.convert_dtype
   1509 )
   1511 if len(mapped) and isinstance(mapped[0], ABCSeries):
   1512     # GH#43986 Need to do list(mapped) in order to get treated as nested
   1513     #  See also GH#25959 regarding EA support
   1514     return obj._constructor_expanddim(list(mapped), index=obj.index)

File ~\anaconda3\lib\site-packages\pandas\core\base.py:921, in IndexOpsMixin._map_values(self, mapper, na_action, convert)
    918 if isinstance(arr, ExtensionArray):
    919     return arr.map(mapper, na_action=na_action)
--> 921 return algorithms.map_array(arr, mapper, na_action=na_action, convert=convert)

File ~\anaconda3\lib\site-packages\pandas\core\algorithms.py:1743, in map_array(arr, mapper, na_action, convert)
   1741 values = arr.astype(object, copy=False)
   1742 if na_action is None:
-> 1743     return lib.map_infer(values, mapper, convert=convert)
   1744 else:
   1745     return lib.map_infer_mask(
   1746         values, mapper, mask=isna(values).view(np.uint8), convert=convert
   1747     )

File lib.pyx:2972, in pandas._libs.lib.map_infer()

Cell In[119], line 12, in euro_to_float(value)
      9 def euro_to_float(value):
     10     # Reemplazar el punto por nada (eliminar separador de miles)
     11     # y la coma por punto (para decimales si los hubiera)
---> 12     return float(value.replace('.', '').replace(',', '.'))

AttributeError: 'float' object has no attribute 'replace'
In [120]:
df_sales_country=df_espanol.groupby([ 'RegionPedido'])['Ventas1'].sum().reset_index(name='Sales of Orders').sort_values(by= 'Sales of Orders', ascending= False)
px.bar(df_sales_country.head(10), x='Sales of Orders',y = 'RegionPedido',color ='Sales of Orders')
In [121]:
#Order Country
df_sales_country=df_espanol.groupby([ 'PaisPedido'])['Ventas1'].sum().reset_index(name='Sales of Orders').sort_values(by= 'Sales of Orders', ascending= False)
fig=px.bar(df_sales_country.head(10), x='Sales of Orders',y = 'PaisPedido',color ='Sales of Orders')
fig.show()

productos¶

In [122]:
#Product
df_sales_country=df_espanol.groupby([ 'NombreProducto'])['Ventas1'].sum().reset_index(name='Sales of Orders').sort_values(by= 'Sales of Orders', ascending= False)
fig=px.bar(df_sales_country.head(10), x='Sales of Orders',y = 'NombreProducto',color ='Sales of Orders')
fig.show()

producto segun el estado de entrega¶

In [131]:
#Product and deliveray status
df_sales_pd=df_espanol.groupby([ 'NombreProducto', 'EstadoEntrega'])['Ventas1'].sum().reset_index(name='Sales of Orders').sort_values(by= 'Sales of Orders', ascending= False)
px.bar(df_sales_pd.head(10), x='Sales of Orders',y = 'NombreProducto',color ='EstadoEntrega')

productos y regiones de la orden¶

In [129]:
#Product and order region
df_sales_pr=df_espanol.groupby([ 'NombreProducto', 'RegionPedido'])['Ventas1'].sum().reset_index(name='Sales of Orders').sort_values(by= 'Sales of Orders', ascending= False)
fig=px.bar(df_sales_pr.head(10), x='Sales of Orders',y = 'NombreProducto',color ='RegionPedido')
fig.show()

categorias¶

In [134]:
#'Category Name'
df_sales_pr=df_espanol.groupby([  'Categoria'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
px.bar(df_sales_pr.head(10), x='Ventas1',y = 'Categoria',color ='Categoria')

segun el tipo de pago¶

In [135]:
#'Type of payment
df_sales_pr=df_espanol.groupby([ 'Pago'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
px.bar(df_sales_pr.head(10), x='Ventas1',y = 'Pago',color ='Ventas1')

ver esto.....¶

In [145]:
df_sales_tp=df_espanol.groupby([ 'NombreProducto','Pago'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
fig=px.bar(df_sales_tp.head(100), x='Ventas1',y = 'Pago',color ='NombreProducto')
fig.show()

analisis de ventas segun las fechas¶

In [243]:
import datetime as dt

data_orderdate=df_espanol[['FechaEnvio', 'Ventas1']]
data_orderdate['order_date'] = pd.to_datetime(data_orderdate['FechaEnvio'])
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\1666086263.py:4: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

In [244]:
data_orderdate["Quarter"] = data_orderdate['order_date'].dt.quarter
data_orderdate["Month"] = data_orderdate['order_date'].dt.month
data_orderdate["year"] = data_orderdate['order_date'].dt.year
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\3482627655.py:1: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\3482627655.py:2: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\3482627655.py:3: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

In [245]:
data_orderdate["Quarter"] = data_orderdate['order_date'].dt.quarter
data_orderdate["Month"] = data_orderdate['order_date'].dt.month
data_orderdate["year"] = data_orderdate['order_date'].dt.year
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\3482627655.py:1: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\3482627655.py:2: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\3482627655.py:3: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

In [246]:
data_orderdate['YearStr']=data_orderdate['year'].astype(str)
df_sales_year=data_orderdate.groupby([ 'YearStr'])['Ventas1'].sum().reset_index(name='Sales of Orders').sort_values(by= 'Sales of Orders', ascending= False)
fig=px.bar(df_sales_year, x='Sales of Orders',y = 'YearStr',color ='Sales of Orders')
fig.show()
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\736912763.py:1: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

In [247]:
data_orderdate['QuarterStr']=data_orderdate['Quarter'].astype(str)
df_sales_quarter=data_orderdate.groupby([ 'YearStr','QuarterStr'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
fig=px.bar(df_sales_quarter, x='Ventas1',y = 'QuarterStr',color ='YearStr')
fig.show()
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\2549423506.py:1: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

In [248]:
data_orderdate['MonthStr']=data_orderdate['Month'].astype(str)
df_sales_m=data_orderdate.groupby([ 'QuarterStr', 'MonthStr'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
fig=px.bar(df_sales_m, x='Ventas1',y = 'QuarterStr',color ='MonthStr')
fig.show()
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\1003044912.py:1: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

In [250]:
data_orderdate['YearStr']=data_orderdate['Month'].astype(str)
df_sales_quarter=data_orderdate.groupby([ 'YearStr','Month'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
fig=px.bar(df_sales_quarter, x='YearStr',y = 'Ventas1',color ='Month')
fig.show()
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\2218752510.py:1: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

In [251]:
data_orderdate['YearStr'].unique()
Out[251]:
array(['4', '3', '2', '1', '5', '6'], dtype=object)
In [255]:
# Primero, convertimos la columna a tipo datetime
df_espanol['FechaEnvio'] = pd.to_datetime(df_espanol['FechaEnvio'])

# Ahora creamos las nuevas columnas
df_espanol['dia'] = df_espanol['FechaEnvio'].dt.day
df_espanol['mes'] = df_espanol['FechaEnvio'].dt.month
df_espanol['anio'] = df_espanol['FechaEnvio'].dt.year


# Si quieres que el formato sea exactamente como 1-18-2018, puedes hacer:
df_espanol['fecha_formateada'] = df_espanol['FechaEnvio'].dt.strftime('%d-%m-%Y')


data_orderdate['YearStr']=data_orderdate['Month'].astype(str)
df_sales_quarter=df_espanol.groupby([ 'anio','mes'])['Ventas1'].count().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
fig=px.bar(df_sales_quarter, x='anio',y = 'Ventas1',color ='Ventas1')
fig.show()
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\1173019489.py:14: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

In [158]:
df_espanol.info()
<class 'pandas.core.frame.DataFrame'>
Index: 23090 entries, 84 to 179628
Data columns (total 32 columns):
 #   Column                      Non-Null Count  Dtype  
---  ------                      --------------  -----  
 0   Pago                        23090 non-null  object 
 1   DiasEnvio(Real)             23090 non-null  int64  
 2   DiasEnvio(Programado)       23090 non-null  int64  
 3   BeneficioPorPedido          23090 non-null  float64
 4   EstadoEntrega               23090 non-null  object 
 5   RiesgoEntregaTardia         23090 non-null  int64  
 6   Categoria                   23090 non-null  object 
 7   PaisCliente                 23090 non-null  object 
 8   IDCliente                   23090 non-null  int64  
 9   SegmentoCliente             23090 non-null  object 
 10  PaisPedido                  23090 non-null  object 
 11  FechaPedido                 23090 non-null  object 
 12  IDPedido                    23090 non-null  int64  
 13  IDArticuloPedido            23090 non-null  int64  
 14  PrecioArticuloPedido        23090 non-null  object 
 15  CantidadArticulosPedido     23090 non-null  int64  
 16  Ventas                      23090 non-null  float64
 17  TotalArticulosPedido        23090 non-null  object 
 18  GananciaPorPedido           23090 non-null  object 
 19  RegionPedido                23090 non-null  object 
 20  DestinoPedido               23090 non-null  object 
 21  EstadoPedido                23090 non-null  object 
 22  IDProducto                  23090 non-null  int64  
 23  CategoriaProducto           23090 non-null  int64  
 24  NombreProducto              23090 non-null  object 
 25  PrecioProducto              23090 non-null  object 
 26  FechaEnvio                  23090 non-null  object 
 27  ModoEnvio                   23090 non-null  object 
 28  Clean Price                 23090 non-null  float64
 29  clean_Beneficio_por_pedido  23090 non-null  float64
 30  Customer_ID_STR             23090 non-null  object 
 31  Ventas1                     23090 non-null  float64
dtypes: float64(5), int64(9), object(18)
memory usage: 5.8+ MB

titulo de esto...........

#separar la fecha

In [161]:
# Primero, convertimos la columna a tipo datetime
df_espanol['FechaEnvio'] = pd.to_datetime(df_espanol['FechaEnvio'])

# Ahora creamos las nuevas columnas
df_espanol['dia'] = df_espanol['FechaEnvio'].dt.day
df_espanol['mes'] = df_espanol['FechaEnvio'].dt.month
df_espanol['anio'] = df_espanol['FechaEnvio'].dt.year


# Si quieres que el formato sea exactamente como 1-18-2018, puedes hacer:
df_espanol['fecha_formateada'] = df_espanol['FechaEnvio'].dt.strftime('%d-%m-%Y')
In [162]:
df_espanol.head()
Out[162]:
Pago DiasEnvio(Real) DiasEnvio(Programado) BeneficioPorPedido EstadoEntrega RiesgoEntregaTardia Categoria PaisCliente IDCliente SegmentoCliente PaisPedido FechaPedido IDPedido IDArticuloPedido PrecioArticuloPedido CantidadArticulosPedido Ventas TotalArticulosPedido GananciaPorPedido RegionPedido DestinoPedido EstadoPedido IDProducto CategoriaProducto NombreProducto PrecioProducto FechaEnvio ModoEnvio Clean Price clean_Beneficio_por_pedido Customer_ID_STR Ventas1 dia mes anio fecha_formateada
84 PAYMENT 4 2 2.347000e+09 Late delivery 1 Women's Apparel Puerto Rico 8541 Home Office Brasil 4/11/2017 15:49 56973 142502 50 3 150.0 144 2.346.999.931 South America Bahía PENDING_PAYMENT 502 24 Nike Men's Dri-FIT Victory Golf Polo 50 2017-04-15 15:49:00 Second Class 50.0 2.347000e+09 8541 0.0015 15 4 2017 15-04-2017
86 PAYMENT 6 2 4.366000e+09 Late delivery 1 Women's Apparel Puerto Rico 3752 Home Office Mexico 3/16/2017 2:54 55155 137932 50 3 150.0 139.5 4.365.999.985 Central America Distrito Federal PENDING_PAYMENT 502 24 Nike Men's Dri-FIT Victory Golf Polo 50 2017-03-22 02:54:00 Second Class 50.0 4.366000e+09 3752 0.0015 22 3 2017 22-03-2017
87 PAYMENT 2 2 1.320000e+09 Shipping on time 0 Women's Apparel Puerto Rico 4673 Home Office Mexico 3/29/2015 10:33 5991 14921 50 3 150.0 132 1.319.999.981 Central America Jalisco PENDING_PAYMENT 502 24 Nike Men's Dri-FIT Victory Golf Polo 50 2015-03-31 10:33:00 Second Class 50.0 1.320000e+09 4673 0.0015 31 3 2015 31-03-2015
88 PAYMENT 4 2 4.620000e+09 Late delivery 1 Women's Apparel Puerto Rico 5367 Home Office Mexico 2/3/2015 00:28 2263 5671 50 3 150.0 132 4.620.000.076 Central America Puebla PENDING_PAYMENT 502 24 Nike Men's Dri-FIT Victory Golf Polo 50 2015-02-07 00:28:00 Second Class 50.0 4.620000e+09 5367 0.0015 7 2 2015 07-02-2015
89 PAYMENT 4 2 1.044000e+09 Late delivery 1 Women's Apparel Puerto Rico 5367 Home Office Mexico 2/3/2015 00:28 2263 5669 50 3 150.0 130.5 1.043.999.958 Central America Puebla PENDING_PAYMENT 502 24 Nike Men's Dri-FIT Victory Golf Polo 50 2015-02-07 00:28:00 Second Class 50.0 1.044000e+09 5367 0.0015 7 2 2015 07-02-2015
In [192]:
#df.rename(columns={'Order Country':'OrderCountry'},inplace=True)

data_orderdate['YearStr']=df_espanol['anio'].astype(str)
fecha=df_espanol['anio'].astype(str)

# Calcular la producción total por año y Provincia
tendencias = df_espanol.groupby(['PaisPedido','anio'])['IDPedido'].count().reset_index()

# Visualizar tendencias a lo largo de los años
plt.figure(figsize=(12, 6))
for OrderCountry in tendencias['PaisPedido'].unique():
    data = tendencias[tendencias['PaisPedido'] == OrderCountry]
    plt.plot(data['anio'], data['IDPedido'], label=OrderCountry)

plt.xlabel('Año')
plt.ylabel('cantidad de pedidos')
plt.title('Tendencias en en pedidos por Años')
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
plt.grid(True)
plt.show()
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\2151799396.py:3: SettingWithCopyWarning:


A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

In [189]:
 import pandas as pd
import plotly.graph_objects as go

# Asumiendo que tu DataFrame se llama 'tendencias'
# y tiene las columnas 'PaisPedido', 'anio', y 'IDPedido'

# Crear una figura
fig = go.Figure()

# Iterar a través de países únicos
for pais in tendencias['PaisPedido'].unique():
    # Filtrar datos para el país actual
    data_pais = tendencias[tendencias['PaisPedido'] == pais]
    
    # Agregar una línea para cada país
    fig.add_trace(go.Scatter(
        x=data_pais['anio'],
        y=data_pais['IDPedido'],
        mode='lines',
        name=pais
    ))

# Personalizar el diseño del gráfico
fig.update_layout(
    title='Tendencias en pedidos por Años',
    xaxis_title='Año',
    yaxis_title='Cantidad de Pedidos',
    legend_title_text='País',
    legend=dict(
        yanchor="top",
        y=0.99,
        xanchor="left",
        x=0.01
    )
)

# Agregar líneas de cuadrícula
fig.update_xaxes(showgrid=True)
fig.update_yaxes(showgrid=True)

# Mostrar el gráfico
fig.show()
In [ ]:
 
In [ ]:
 
In [194]:
#df_argentina.rename(columns={'Order Country':'OrderCountry'},inplace=True)
#df_argentina = df[df['OrderCountry'] == 'Argentina']
#df_argentina.rename(columns={'Order City':'OrderCity'},inplace=True)

#data_orderdate['YearStr']=df['anio'].astype(str)
#fecha=df_argentina['anio'].astype(str)

# Calcular la producción total por año y Provincia
tendencias = df_espanol.groupby(['RegionPedido','anio'])['IDPedido'].count().reset_index()

# Visualizar tendencias a lo largo de los años
plt.figure(figsize=(12, 6))
for OrderCity in tendencias['RegionPedido'].unique():
    data = tendencias[tendencias['RegionPedido'] == OrderCity]
    plt.plot(data['anio'], data['IDPedido'], label=OrderCity)

plt.xlabel('Año')
plt.ylabel('cantidad de pedidos')
plt.title('Tendencias en en pedidos por meses')
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
plt.grid(True)
plt.show()
In [196]:
 import pandas as pd
import plotly.graph_objects as go

# Asumiendo que tu DataFrame se llama 'tendencias'
# y tiene las columnas 'PaisPedido', 'anio', y 'IDPedido'

# Crear una figura
fig = go.Figure()

# Iterar a través de países únicos
for pais in tendencias['RegionPedido'].unique():
    # Filtrar datos para el país actual
    data_pais = tendencias[tendencias['RegionPedido'] == pais]
    
    # Agregar una línea para cada país
    fig.add_trace(go.Scatter(
        x=data_pais['anio'],
        y=data_pais['IDPedido'],
        mode='lines',
        name=pais
    ))

# Personalizar el diseño del gráfico
fig.update_layout(
    title='Tendencias en pedidos por Años',
    xaxis_title='Año',
    yaxis_title='Cantidad de Pedidos',
    legend_title_text='País',
    legend=dict(
        yanchor="top",
        y=0.99,
        xanchor="left",
        x=0.01
    )
)

# Agregar líneas de cuadrícula
fig.update_xaxes(showgrid=True)
fig.update_yaxes(showgrid=True)

# Mostrar el gráfico
fig.show()
In [203]:
df_espanol['PrecioProducto'] = df_espanol['PrecioProducto'].apply(clean_Beneficio_por_pedido)
df_espanol['Precio2'] = df_espanol['PrecioProducto']/1000
In [218]:
# vamos a probar agregar una columna donde se divida el valor de la orden para ver si se puede dibujar
#df.rename(columns={'Order Country':'OrderCountry'},inplace=True)
#data_orderdate['YearStr']=df['anio'].astype(str)
#fecha=df['anio'].astype(str)

# Calcular la producción total por año y Provincia
tendencias = df_espanol.groupby(['NombreProducto','anio'])['PrecioProducto'].sum().reset_index()

# Visualizar tendencias a lo largo de los años
plt.figure(figsize=(12, 6))
for OrderCountry in tendencias['NombreProducto'].unique():
    data = tendencias[tendencias['NombreProducto'] == OrderCountry]
    plt.plot(data['anio'], data['PrecioProducto'], label=OrderCountry)

plt.xlabel('Año')
plt.ylabel('cantidad de pedidos')
plt.title('Tendencias en en pedidos por Años')
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
plt.grid(True)
plt.show()
In [227]:
#CANTIDAD DE PEDIDOS POR AÑO SEGUN EL PRODUCTO
In [226]:
import pandas as pd
import plotly.graph_objects as go

# Asumiendo que tu DataFrame se llama 'tendencias'
# y tiene las columnas 'PaisPedido', 'anio', y 'IDPedido'

# Crear una figura
fig = go.Figure()

# Iterar a través de países únicos
for pais in tendencias['NombreProducto'].unique():
    # Filtrar datos para el país actual
    data_pais = tendencias[tendencias['NombreProducto'] == pais]
    
    # Agregar una línea para cada país
    fig.add_trace(go.Scatter(
        x=data_pais['anio'],
        y=data_pais['IDPedido'],
        mode='lines',
        name=pais
    ))

# Personalizar el diseño del gráfico
fig.update_layout(
    title='Tendencias en pedidos por Años',
    xaxis_title='Año',
    yaxis_title='Cantidad de Pedidos',
    legend_title_text='País',
    legend=dict(
        yanchor="top",
        y=0.99,
        xanchor="left",
        x=0.01
    )
)

# Agregar líneas de cuadrícula
fig.update_xaxes(showgrid=True)
fig.update_yaxes(showgrid=True)

# Mostrar el gráfico
fig.show()
In [ ]:
 
In [ ]:
#Agregar los boxplots
#ejemplo de codigo

# REEMPLAZAR POR EL OTRO CODIGO
import plotly.express as px
df = px.data.tips()
fig = px.box(df, y="total_bill")
fig.show()

Análisis Univariado:¶

Distribución de Variables: Realizar un análisis de las variables individuales para entender su distribución. Utilizar histogramas, boxplots y estadísticas descriptivas (media, mediana, desviación estándar, etc.) para las variables numéricas. Para las variables categóricas, calcular frecuencias y proporciones. Identificación de Outliers: Detectar posibles outliers en las variables numéricas utilizando técnicas como el análisis de boxplots o el cálculo del z-score.

Análisis Bivariado:¶

Relaciones entre Variables: Analizar la relación entre pares de variables para identificar patrones o correlaciones. Utilizar gráficos de dispersión (scatter plots) y mapas de calor de correlación (heatmaps) para evaluar la relación entre variables numéricas. Comparaciones Categóricas: Explorar cómo las variables categóricas afectan a las variables numéricas, utilizando gráficos de barras y boxplots.

Limpieza de Datos:¶

Tratamiento de Valores Faltantes: Identificar valores faltantes en el conjunto de datos. Aplicar métodos adecuados para el tratamiento de estos valores, ya sea mediante imputación, eliminación de filas/columnas o sustitución con valores medianos/modales. Normalización y Transformación: Realizar transformaciones necesarias para preparar los datos para el análisis posterior. Esto puede incluir normalización y estandarización

In [ ]:
# solo faltan algo de analisis bivariado y limpieza
In [ ]:
# hay que definir bien las columnas que quedan si se van a utilizar luego para la 3 entrega
In [ ]:
 
In [256]:
df_espanol['anio'].unique()
Out[256]:
array([2017, 2015])
In [ ]:
#FALTAN AÑOS,.............VER LA FUNCION QUE DIVIDE LA FECHA DE ENVIO